#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include "wrap.h"
void free_process(int arg){
    pid_t pid;

    while (1) {
        pid = waitpid(-1,NULL,WNOHANG);
        // 没有要等待的子进程
        if(pid <= 0){
            break;
        }
        // 没有子进程退出
        else if(pid == 0){
            break;
        }
        //
        else {
            printf("子进程退出并回收资源 pid : %d\n",pid);
        }

    }

}

/**
 * 多进程实现并发服务器
 * gcc main.c wrap.c
 * @return
 */
int main() {

    // 使用信号集 屏蔽某个信号
    sigset_t block_set;
    sigemptyset(&block_set);
    sigaddset(&block_set,SIGCHLD);
    sigprocmask(SIG_BLOCK,&block_set,NULL);

    //创建套接字 绑定
    int socket_fd = tcp4bind(8080,NULL);
    //监听
    Listen(socket_fd,128);
    struct sockaddr_in client_addr;
    socklen_t len = sizeof(client_addr);
    while (1){
        //提取
        int client_fd = Accept(socket_fd,(struct sockaddr *)&client_addr,&len);
        char ip[16] = "";
        printf("客户端：%s:%d 链接了服务器。。。。。。！\n", inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,ip,16), ntohs(client_addr.sin_port));
        pid_t pid = fork();
        //      进程创建失败
        if(pid < 0){
            perror("fork");
            close(socket_fd);
            exit(1);
        }
        //      子进程
        else if(pid == 0){
            //
            close(socket_fd);
            //回射
            while (1){
                char buff[1024] = "";
                int n = read(client_fd,buff, sizeof(buff));
                if(n < 0){
                    perror("read");
                    close(client_fd);
                    exit(1);
                }
                else if(n == 0){
                    printf("客户端：%s:%d 断开了和服务器的链接。。。。。。！\n", inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,ip,16), ntohs(client_addr.sin_port));
                    close(client_fd);
                    exit(0);
                }
                else {
                    printf("%s:%s",ip,buff);
                    write(client_fd,buff,n);
                }
            }

        }
        //      父进程
        else {
            close(client_fd);
            //      回收子进程资源
            //      注册信号回调
            struct sigaction act;
            act.sa_flags = 0;
            act.sa_handler = free_process;
            sigemptyset(&act.sa_mask);
            sigaction(SIGCHLD,&act,NULL);

            //解开信号集屏蔽
            sigprocmask(SIG_UNBLOCK,&block_set,NULL);
        }

    }

    //关闭
    close(socket_fd);
    //
    //
    //
    //


    return 1;
}

